package com.pipe.util;

import io.netty.buffer.ByteBuf;

import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Kiven
 */
public class MysqlProtocolUtil {
    private static Pattern pattern = Pattern.compile("([0-9]*)");

    public static int getLengthFromTypeString(String type) {
        Matcher matcher = pattern.matcher(type);
        while (matcher.find()) {
            String result = matcher.group();
            if (!matcher.group().isEmpty()){
                return Integer.valueOf(result);
            }
        }
        return 0;
    }

    /**
     * 合并两个长度为2的数组
     *
     * @param lowerArr
     * @param higherArr
     * @return
     */
    public static byte[] merge2Arr(byte[] lowerArr, byte[] higherArr) {
        byte[] newArr = new byte[4];
        System.arraycopy(lowerArr, 0, newArr, 0, 2);
        System.arraycopy(higherArr, 0, newArr, 2, 2);
        return newArr;
    }

    /**
     * 字符串转数组末尾加0
     *
     * */
    public static byte[] string2arrZeroTail(String str){
        byte[] strArr = str.getBytes();
        byte[] newArr = new byte[strArr.length + 1];
        System.arraycopy(strArr, 0, newArr, 0, strArr.length);
        return newArr;
    }

    public static byte[] merge2seed(byte[] lowerArr, byte[] higherArr){
        byte[] newArr = new byte[20];
        System.arraycopy(lowerArr, 0, newArr, 0, 8);
        System.arraycopy(higherArr, 0, newArr, 8,  12);
        return newArr;
    }

    /**获取尾部为0x00的byte数组*/
    public static byte[] getNullTailBytes(ByteBuf byteBuf) throws Exception {
        for(int i = 0; i < byteBuf.readableBytes() ; i++){
            if (byteBuf.getByte(i) == 0x00){
                byte[] arr = new byte[i - 1];
                byteBuf.readBytes(arr);
                byteBuf.readByte(); //跳过00
                return arr;
            }
        }
        throw new Exception("0x00 tail not found!");
    }

    public static byte[] readLenencStringOfByteFromBytebuf(ByteBuf byteBuf){
        long stringLen = readLenencIntFromBytebuf(byteBuf);
        byte[] newStrArr = new byte[(int) stringLen];
        byteBuf.readBytes(newStrArr);
        return newStrArr;
    }

    public static String readStringFromBytebuf(ByteBuf byteBuf){
        CharSequence charSequence = byteBuf.readCharSequence(byteBuf.readableBytes(), Charset.forName("UTF-8"));
        return charSequence.toString();
    }

    public static String readLenencStringFromBytebuf(ByteBuf byteBuf){
        return new String(readLenencStringOfByteFromBytebuf(byteBuf));
    }

    public static String readRowLenencStringFromBytebuf(ByteBuf byteBuf){
        long stringLen = readLenencIntFromBytebuf(byteBuf);
        if (stringLen == 0xfb){
            return null;
        }
        byte[] newStrArr = new byte[(int) stringLen];
        byteBuf.readBytes(newStrArr);
        return new String(newStrArr);
    }

    /**从bytebuf中直接读取 lenenc_int*/
    public static long readLenencIntFromBytebuf(ByteBuf byteBuf){
        byte[] values = null;
        short firstNum = byteBuf.readUnsignedByte();
        if (firstNum <= 0xfb){
            return firstNum;
        }
        if (firstNum == 0xfc){
            values = new byte[2];
            values[1] = byteBuf.readByte();
            values[0] = byteBuf.readByte();
            return IntegerConveter.getIntFromByte2(values);
        }
        if (firstNum == 0xfd){
            values = new byte[3];
            values[2] = byteBuf.readByte();
            values[1] = byteBuf.readByte();
            values[0] = byteBuf.readByte();
            return IntegerConveter.getIntFromByte3(values);
        }
        if (firstNum == 0xfe){
            values = new byte[8];
            values[7] = byteBuf.readByte();
            values[6] = byteBuf.readByte();
            values[5] = byteBuf.readByte();
            values[4] = byteBuf.readByte();
            values[3] = byteBuf.readByte();
            values[2] = byteBuf.readByte();
            values[1] = byteBuf.readByte();
            values[0] = byteBuf.readByte();
            return IntegerConveter.getLongFromByte(values);
        }
        throw new IllegalArgumentException("wrong number!");
    }
}